package com.itmyx.base.util.codegeneration;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.itmyx.base.util.String.StringChangeUtil;

/**
 * 功能描述    数据库表结构相关
 * @类型名称 TableUtil
 * @版本 1.0
 * @创建者 myx
 * @创建时间 2016年9月9日 上午10:36:46
 * @版权所有 @2016 ITMYX
 * @修改者 myx
 * @修改时间 2016年9月9日 上午10:36:46
 * @修改描述
 */
public class TableUtil {
	
	private static final String DRIVER_CLASS = "com.mysql.jdbc.Driver";
    private static final String DATABASE_URL = "jdbc:mysql://127.0.0.1:3306/ssm";
    private static final String DATABASE_USER = "root";
    private static final String DATABASE_PASSWORD = "root";
    private static Connection con = null;
    
    /**
     * 概述：	获取连接
     * 方法编号： 				
     * 相关业务 ：		
     * 实现原理：		
     * 其他：			
     * -----------------------------------------------------
     * 版本：			
     * 创建者：		
     * 创建时间：		2016年9月9日	下午3:56:05
     * 最后更新者：		myx
     * 最后更新时间：	2016年9月9日 下午3:56:05
     * -----------------------------------------------------
     * 时间：			2016年9月9日 下午3:56:05
     * 版本：			
     * 修改类型：		
     * 修改内容：		
     * 修改人：		myx
     * -----------------------------------------------------
     * 
     * @return
     */
    public static Connection getConnection() {
        try {
            Class.forName(DRIVER_CLASS);
            con=DriverManager.getConnection(DATABASE_URL,DATABASE_USER,DATABASE_PASSWORD);
            return con;
        } catch (Exception ex) {
            System.out.println("2:"+ex.getMessage());
        }
        return con;
    }
	
    /**
     * 概述：	获取所有表数据
     * 方法编号： 				
     * 相关业务 ：		
     * 实现原理：		
     * 其他：			
     * -----------------------------------------------------
     * 版本：			
     * 创建者：		
     * 创建时间：		2016年9月9日	下午3:56:24
     * 最后更新者：		myx
     * 最后更新时间：	2016年9月9日 下午3:56:24
     * -----------------------------------------------------
     * 时间：			2016年9月9日 下午3:56:24
     * 版本：			
     * 修改类型：		
     * 修改内容：		
     * 修改人：		myx
     * -----------------------------------------------------
     * 
     * @param conn
     * @return
     */
    public static List<Map<String,Object>>  getTablesByCon(Connection conn) {
    	List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
    	try {
    		DatabaseMetaData databaseMetaData = conn.getMetaData();
    		/*其中"%"就是表示*的意思，也就是任意所有的意思。其中m_TableName就是要获取的数据表的名字，如果想获取所有的表的名字，就可以使用"%"来作为参数了。*/
    		ResultSet tableSet = databaseMetaData.getTables(null, "%", "%", new String[]{"TABLE"});
    		while (tableSet.next()) {
    			Map<String,Object> map = new HashMap<String, Object>();
		    	String tableName = tableSet.getString("TABLE_NAME").toLowerCase();
		    	String tableComment = tableSet.getString("REMARKS");
		    	map.put("tableName",tableName);
		    	map.put("tableComment",tableComment);
		    	list.add(map);
			}
		} catch (Exception e) {
			
		}
		return list;
	}
    
    
    /**
     * 概述：	获取表下所有字段信息
     * 方法编号： 				
     * 相关业务 ：		
     * 实现原理：		
     * 其他：			
     * -----------------------------------------------------
     * 版本：			
     * 创建者：		
     * 创建时间：		2016年9月9日	下午3:56:53
     * 最后更新者：		myx
     * 最后更新时间：	2016年9月9日 下午3:56:53
     * -----------------------------------------------------
     * 时间：			2016年9月9日 下午3:56:53
     * 版本：			
     * 修改类型：		
     * 修改内容：		
     * 修改人：		myx
     * -----------------------------------------------------
     * 
     * @param conn
     * @param tableName
     * @return
     */
    public static List<Map<String,Object>>  getColumnInfoByCon(Connection conn,String tableName) {
    	List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
    	try {
    		DatabaseMetaData databaseMetaData = conn.getMetaData();
    		/*JDBC里面通过getColumns的接口，实现对字段的查询。跟getTables一样，"%"表示所有任意的（字段），而m_TableName就是数据表的名字。*/
    		ResultSet columnSet = databaseMetaData.getColumns(null, "%", tableName, "%");
	    	while (columnSet.next()) {
	    		Map<String,Object> map = new HashMap<String, Object>();
	    		String columnName = columnSet.getString("COLUMN_NAME");
	    		String typeName = columnSet.getString("TYPE_NAME");
	    		String columnRemark = columnSet.getString("REMARKS");
	    		map.put("columnName",columnName);
	    		map.put("columnType",typeName.toLowerCase());
	    		map.put("columnRemark",columnRemark);
	    		map.put("attrName",StringChangeUtil.classNameFirstLowerCase(StringChangeUtil._ToUpperNextCase(columnName.toLowerCase(),null)));
	    		map.put("attrNameFirstUpperCase",StringChangeUtil._ToUpperNextCase(columnName.toLowerCase(),null));
		    	
	    		//TODO:判断是什么数据库
	    		map.put("attrType",TypeUtil.mysqlTypeToJavaType(typeName.toLowerCase()));//属性类型
		    	map.put("jdbcType",TypeUtil.mysqlTypeToJdbcType(typeName.toLowerCase()));
		    	list.add(map);
			}
		} catch (Exception e) {
			
		}
		return list;
	}
    


	/*tableSet有以下列
	TABLE_CAT String => 表类别（可为 null）
	TABLE_SCHEM String => 表模式（可为 null）
	TABLE_NAME String => 表名称
	TABLE_TYPE String => 表类型。典型的类型是 "TABLE"、"VIEW"、"SYSTEM TABLE"、"GLOBAL TEMPORARY"、"LOCAL TEMPORARY"、"ALIAS" 和 "SYNONYM"。
	REMARKS String => 表的解释性注释
	TYPE_CAT String => 类型的类别（可为 null）
	TYPE_SCHEM String => 类型模式（可为 null）
	TYPE_NAME String => 类型名称（可为 null）
	SELF_REFERENCING_COL_NAME String => 有类型表的指定 "identifier" 列的名称（可为 null）
	REF_GENERATION String => 指定在 SELF_REFERENCING_COL_NAME 中创建值的方式。这些值为 "SYSTEM"、"USER" 和 "DERIVED"。（可能为 null）*/
	
	
	
	
	/*每个列描述都有以下列： 

	TABLE_CAT String => 表类别（可为 null） 
	TABLE_SCHEM String => 表模式（可为 null） 
	TABLE_NAME String => 表名称 
	COLUMN_NAME String => 列名称 
	DATA_TYPE int => 来自 java.sql.Types 的 SQL 类型 
	TYPE_NAME String => 数据源依赖的类型名称，对于 UDT，该类型名称是完全限定的 
	COLUMN_SIZE int => 列的大小。 
	BUFFER_LENGTH 未被使用。 
	DECIMAL_DIGITS int => 小数部分的位数。对于 DECIMAL_DIGITS 不适用的数据类型，则返回 Null。 
	NUM_PREC_RADIX int => 基数（通常为 10 或 2） 
	NULLABLE int => 是否允许使用 NULL。 
	columnNoNulls - 可能不允许使用 NULL 值 
	columnNullable - 明确允许使用 NULL 值 
	columnNullableUnknown - 不知道是否可使用 null 
	REMARKS String => 描述列的注释（可为 null） 
	COLUMN_DEF String => 该列的默认值，当值在单引号内时应被解释为一个字符串（可为 null） 
	SQL_DATA_TYPE int => 未使用 
	SQL_DATETIME_SUB int => 未使用 
	CHAR_OCTET_LENGTH int => 对于 char 类型，该长度是列中的最大字节数 
	ORDINAL_POSITION int => 表中的列的索引（从 1 开始） 
	IS_NULLABLE String => ISO 规则用于确定列是否包括 null。 
	YES --- 如果参数可以包括 NULL 
	NO --- 如果参数不可以包括 NULL 
	空字符串 --- 如果不知道参数是否可以包括 null 
	SCOPE_CATLOG String => 表的类别，它是引用属性的作用域（如果 DATA_TYPE 不是 REF，则为 null） 
	SCOPE_SCHEMA String => 表的模式，它是引用属性的作用域（如果 DATA_TYPE 不是 REF，则为 null） 
	SCOPE_TABLE String => 表名称，它是引用属性的作用域（如果 DATA_TYPE 不是 REF，则为 null） 
	SOURCE_DATA_TYPE short => 不同类型或用户生成 Ref 类型、来自 java.sql.Types 的 SQL 类型的源类型（如果 DATA_TYPE 不是 DISTINCT 或用户生成的 REF，则为 null） 
	IS_AUTOINCREMENT String => 指示此列是否自动增加 
	YES --- 如果该列自动增加 
	NO --- 如果该列不自动增加 
	空字符串 --- 如果不能确定该列是否是自动增加参数 
	COLUMN_SIZE 列表示给定列的指定列大小。对于数值数据，这是最大精度。对于字符数据，这是字符长度。对于日期时间数据类型，这是 String 表示形式的字符长度（假定允许的最大小数秒组件的精度）。对于二进制数据，这是字节长度。对于 ROWID 数据类型，这是字节长度。对于列大小不适用的数据类型，则返回 Null。 


	参数：
	catalog - 类别名称；它必须与存储在数据库中的类别名称匹配；该参数为 "" 表示获取没有类别的那些描述；为 null 则表示该类别名称不应该用于缩小搜索范围
	schemaPattern - 模式名称的模式；它必须与存储在数据库中的模式名称匹配；该参数为 "" 表示获取没有模式的那些描述；为 null 则表示该模式名称不应该用于缩小搜索范围
	tableNamePattern - 表名称模式；它必须与存储在数据库中的表名称匹配
	columnNamePattern - 列名称模式；它必须与存储在数据库中的列名称匹配 */
	
}
